/**
 * 网络请求配置模块
 */

import axios from 'axios'
// 处理超过 js int 取值范围的 int 数据
// 默认的 json.parse 处理 js默认范围的超大 int 数据会有错误
import JSONbig from 'json-bigint'
import store from '@/store'
import { Toast } from 'vant'
import router from '@/router'

const request = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/',
  // 后端返回的数据可能不是 JSON 格式字符串
  // 如果不是的话，那么 JSONbig.parse 调用就会报错
  // 所有我们使用 try-catch 来捕获异常，处理异常的发生
  transformResponse: [
    function(data) {
      try {
        return JSONbig.parse(data)
      } catch (error) {
        // 如果转换失败，把数据原封不动的直接返给请求使用
        console.log('转换失败', error)
        return data
      }

      // axios 默认在内部使用 JSON.parse 来转换处理原始数据
    }
  ]
})

// 请求拦截器
request.interceptors.request.use(
  config => {
    const { user } = store.state
    // 如果不存在 用户信息 user 则说明未登录，不用携带 token 信息
    if (user) {
      config.headers.Authorization = `Bearer ${user.token}`
    }

    return config
  },
  err => {
    console.log(err)
  }
)

const refrashTokenReq = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/'
})

// 响应拦截器
// 这个 401 权限的处理逻辑理一下
request.interceptors.response.use(
  response => {
    return response
  },
  async error => {
    // 请求响应失败会进入这里
    // 超过 2XX 的状态码都会进入这里
    const status = error.response.status
    if (status === 400) {
      Toast.fail('客户端请求参数异常')
    } else if (status === 401) {
      // token 无效
      // 如果没有 user 或者 user.token 直接去登录
      const { user } = store.state
      if (!user || !user.token) {
        return redirectLogin()
      }
      // 如果有 refresh_token，则请求获取新的 token
      try {
        const { data } = await refrashTokenReq({
          method: 'PUT',
          url: '/app/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${user.refresh_token}`
          }
        })
        console.log(data, 'gettoken')
        // 拿到新的 token 之后把它更新到容器中
        user.token = data.data.token
        store.commit('setUserInfo', { user })

        // 把失败的请求重新发出去
        // error.config 是本次请求的相关配置信息对象
        return request(error.config)
      } catch (error) {
        // 刷新 token 失败，直接跳转到登录页重新登录
        redirectLogin()
      }
    } else if (status === 403) {
      Toast.fail('无权限')
    } else if (status >= 500) {
      Toast.fail('服务端异常')
    }

    return Promise.reject(error)
  }
)

function redirectLogin() {
  router.replace({
    // 传递查询参数，查询参数会以 ？ 作为分隔符放到 url 后面
    name: 'login',
    query: {
      // 自己定义的字段名
      // router.currentRoute 和我们在组件中获取的 this.$route 是同样的
      redirectPath: router.currentRoute.fullPath
    }
  })
}

export default request
